package com.rookieci.plugin.core;

import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.res.AssetManager;
import android.content.res.Resources;

import java.io.File;
import java.lang.reflect.Method;

import dalvik.system.DexClassLoader;

/**
 * Created by 磁磁帅 on 2023/4/27 0027.
 * 功能：
 * 我们这个类的目的就是为了记载外部的Apk,为什么呢，因为插件类实际上只是以文件的新式存在，
 * app启动时候系统并不会加载外部插件类，所以我们要手动通过这个类加载外部的apk.
 **/
public class PluginManager {
    private static Context mContext;
    //加载外部的DexClassLoader
    private DexClassLoader mDexClassLoader;
    //资源管理
    private Resources mResources;
    //包信息管理类
    private PackageInfo mPackageInfo;

    //一定要先调用这个方法，不然会报错
    public static void init(Context context) {
        mContext = context;
    }

    private static PluginManager instance = new PluginManager();

    private PluginManager() {
    }

    public static PluginManager getInstance() {
        return instance;
    }

    //这个方法就是用来加载指定路径的外部Apk路径的
    public void loadDex(String apkPath) {
        //创建缓存路径
        //File file = mContext.getDir("plugin", Context.MODE_PRIVATE);
        File file = new File(apkPath).getParentFile();
        mDexClassLoader = new DexClassLoader(apkPath, file.getAbsolutePath(), null, mContext.getClassLoader());
        mPackageInfo = mContext.getPackageManager().getPackageArchiveInfo(apkPath, PackageManager.GET_ACTIVITIES);
        try {
            AssetManager assetManager = AssetManager.class.newInstance();
            Method addAssetPath = assetManager.getClass().getDeclaredMethod("addAssetPath", String.class);
            addAssetPath.invoke(assetManager, apkPath);
            mResources = new Resources(assetManager, mContext.getResources().getDisplayMetrics(), mContext.getResources().getConfiguration());
        } catch (Exception e) {
            e.printStackTrace();
        }

        /*try {
            AssetManager assetManager = AssetManager.class.newInstance();
            Method addAssetPath = assetManager.getClass().getMethod("addAssetPath", String.class);
            addAssetPath.invoke(assetManager, apkPath);
            Resources curAppRes = mContext.getResources();
            mResources = new Resources(assetManager, curAppRes.getDisplayMetrics(), curAppRes.getConfiguration());
        } catch (Exception e) {
            e.printStackTrace();
        }*/
    }

    public DexClassLoader getDexClassLoader() {
        return mDexClassLoader;
    }

    public Resources getResources() {
        return mResources;
    }

    public PackageInfo getPackageInfo() {
        return mPackageInfo;
    }
}
